home *** CD-ROM | disk | FTP | other *** search
- // wild.c wildcard AppleScript addition
- //
- // 93/11/15 File created
- // 93/12/08 *** released Wild 0.1.0 ***
- // 93/12/09 moved common files to the THINK C Folder
- // 94/01/24 removed the licensing mechanism with NO_LICENCE
- // 94/01/24 *** released Wild 1.0.0 ***
- // 94/05/09 Totally removed the licensing mechanism and added the GNU comments
- //
- //--------------------------------------------------------------------------------------------------
- // Copyright © 1993, 1994 by Rainbow Hill Pty Ltd.
- //
- // This program is free software; you can redistribute it and/or modify it under the terms of
- // the GNU General Public License as published by the Free Software Foundation; either version 2
- // of the License, or any later version.
- //
- // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- // See the GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License along with this program;
- // if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- //
-
- //#define DEBUG_SHOW_PARM
- //#define DEBUG_SHOW_ITEMS
- //#define DEBUG_SHOW_ERR_MESS
-
- //---------------------------- Apple includes
- #include <Aliases.h>
- #include <AppleEvents.h>
- #include <Errors.h>
- #include <Files.h>
- #include <Resources.h>
-
- //---------------------------- C includes
- #include <string.h>
-
- //---------------------------- other includes
- #include <AERegistry.h>
- #include "parm.h"
- #include "match.h"
- #include "wild.h"
-
- static OSErr addItem(
- FSSpec *, // --> fss of the item to be added
- AEDescList *, // <-> output list to be returned as reply
- char * // <-- error message
- );
-
- //****************************************************************************************** main
- pascal OSErr main(
- AppleEvent event,
- AppleEvent reply,
- long handlerRefCon
- ) {
-
- OSErr retVal;
- AEDescList inList;
- AEDescList outList;
- DescType typeCode;
- Size actualSize;
- char buff[WILD_bufferLength];
- long nItems;
- long kItem;
- FSSpec fss;
- AEKeyword key;
- char errMessage[WILD_bufferLength];
- Ptr aPtr;
- Boolean wasChanged;
- CInfoPBRec param;
- wild_parm_t parms;
- Boolean itMatches;
- Boolean inListCreated;
- Boolean outListCreated;
- char theName[WILD_nameLength]; // [wildcarded] item name from descriptor
- unsigned char paramName[WILD_nameLength];
- short k;
- Boolean itemOK;
- short index;
- match_wild_t wilds[WILD_maxFilenameLen];
- short nWild;
- match_wild_t onlyWilds[WILD_maxFilenameLen];
- short nOnlyWild;
-
- // initialise some variables
- errMessage[0] = '\0';
- outListCreated = false;
- inListCreated = false;
-
- retVal = AEGetParamDesc(&event, keyDirectObject, typeAEList, &inList);
- if (retVal != noErr) {
- # ifdef DEBUG_SHOW_ERR_MESS
- strcpy(errMessage, "AEGetParamDesc");
- # endif
- goto DONE_LBL; // --->
- }
- inListCreated = true;
-
- // extract the parameters from the AE
- retVal = parm_get(&event, &parms, errMessage);
- if (retVal != noErr) goto DONE_LBL; // --->
-
- // check that the user has not switched off both files and folders
- if (parms.files == false && parms.folders == false) {
- retVal = errAEEventNotHandled;
- GetIndString(errMessage, WILD_errMessRsrc, WILD_nothingErrStr);
- p2cstr(errMessage);
- goto DONE_LBL; // --->
- }
-
- # ifdef DEBUG_SHOW_PARM
- {
- #define Place(x, i, what) { \
- i++; \
- strcpy(&x[i], (const char *)what); \
- i += strlen(what) - 1; \
- }
-
- k = 0;
- Place(buff, k, "wild cards: ");
- buff[++k] = parms.longW;
- buff[++k] = parms.shortW;
- Place(buff, k, "\rfile:"); Place(buff, k, ((parms.files) ? "T" : "F"));
- Place(buff, k, " fold:"); Place(buff, k, ((parms.folders) ? "T" : "F"));
- Place(buff, k, " case:"); Place(buff, k, ((parms.caseS) ? "T" : "F"));
- Place(buff, k, " long:"); Place(buff, k, ((parms.doLong) ? "T" : "F"));
- Place(buff, k, " shor:"); Place(buff, k, ((parms.doShort) ? "T" : "F"));
- Place(buff, k, " crea:"); Place(buff, k, ((parms.doCreator) ? "T" : "F"));
- Place(buff, k, " type:"); Place(buff, k, ((parms.doType) ? "T" : "F"));
- if (parms.doCreator) {
- Place(buff, k, "\rcreator: '");
- strncpy(&buff[++k], (const char *)&parms.creator, 4);
- k += 3;
- Place(buff, k, "'");
- }
- if (parms.doType) {
- Place(buff, k, "\rfile type: '");
- strncpy(&buff[++k], (const char *)&parms.type, 4);
- k += 3;
- Place(buff, k, "'");
- }
- buff[0] = k;
- ParamText(buff, "", "", "");
- Alert(WILD_genericDialogRsrc, nil);
- }
- # endif
-
- // get the number of descriptor records in the list
- retVal = AECountItems(&inList, &nItems);
- if (retVal != noErr) {
- # ifdef DEBUG_SHOW_ERR_MESS
- strcpy(errMessage, "AECountItems");
- # endif
- goto DONE_LBL; // --->
- }
-
- // create a descriptor list to return the items which pass filtering
- retVal = AECreateList(nil, (Size)0, false, &outList);
- if (retVal != noErr) {
- # ifdef DEBUG_SHOW_ERR_MESS
- strcpy(errMessage, "AECreateList");
- # endif
- goto DONE_LBL; // --->
- }
- outListCreated = true;
-
- // analyse the wildcards in the selection if there is one
- if (parms.only[0] == '\0')
- nOnlyWild = 0;
- else
- nOnlyWild = match_setWild(parms.only, &parms, onlyWilds);
-
- // get each descriptor from the list
- for (kItem = 1; kItem <= nItems && retVal == noErr; kItem++) {
- retVal = AEGetNthPtr(
- &inList,
- kItem,
- typeWildCard,
- &key,
- &typeCode,
- (Ptr)buff,
- sizeof(buff),
- &actualSize
- );
- if (retVal != noErr) {
- # ifdef DEBUG_SHOW_ERR_MESS
- strcpy(errMessage, "AEGetNthPtr");
- # endif
- goto DONE_LBL; // --->
- }
-
- // determine the type of the descriptor and act accordingly
- nWild = 0;
- switch (typeCode) {
-
- case typeChar: // string
- case typeStyledText:
- case typeIntlText:
- buff[actualSize] = '\0';
-
- // extract the item name from buff
- for (k = actualSize - 1; k >= 0 && buff[k] != ':'; k--)
- ;
- strcpy(theName, (const char *)&buff[k + 1]);
-
- // check whether the name is wildcarded and if so, process wildcards
- nWild = match_setWild(theName, &parms, wilds);
-
- // covert the parameter to an FSS
- c2pstr(buff);
- retVal = FSMakeFSSpec(-1, 2L, buff, &fss);
- p2cstr(buff);
- if (retVal == fnfErr) {
-
- // if the name is wildcarded, we expect not to find it
- if (nWild != 0) {
- retVal = noErr;
- }
- else {
-
- GetIndString(errMessage, WILD_miscStrRsrc, WILD_itemStr);
-
- // append the item number within the input list
- k = errMessage[0] + 1;
- NumToString((long)kItem, &errMessage[k]);
- errMessage[0] += errMessage[k] + 1;
- errMessage[k] = ' '; // mask the second p-length with a space
-
- // append the error string
- k = errMessage[0] + 1;
- GetIndString(&errMessage[k], WILD_errMessRsrc, WILD_notFoundErrStr);
- errMessage[0] += errMessage[k] + 1;
- errMessage[k] = ' '; // mask the second p-length with a space
-
- p2cstr(errMessage);
- goto DONE_LBL; // --->
- }
-
- } // FSMakeFSSpec could not find the item
- else if (retVal != noErr) {
-
- # ifdef DEBUG_SHOW_ERR_MESS
- strcpy(errMessage, "FSMakeFSSpec");
- # endif
- goto DONE_LBL; // --->
- }
-
- break;
-
- case typeAlias: // alias
- aPtr = (Ptr)buff;
- retVal = ResolveAlias(nil, (AliasHandle)&aPtr, &fss, &wasChanged);
- if (retVal != noErr) {
- # ifdef DEBUG_SHOW_ERR_MESS
- strcpy(errMessage, "ResolveAlias");
- # endif
- goto DONE_LBL; // --->
- }
-
- // save the name of the item (which cannot be wildcarded)
- memcpy((void *)theName, (const void *)&fss.name[1], (Size)fss.name[0]);
- theName[fss.name[0]] = '\0';
-
- break;
-
- default: // a type of descriptor that we do not process
- retVal = errAEWrongDataType;
- GetIndString(errMessage, WILD_errMessRsrc, WILD_dirParDataErrStr);
- p2cstr(errMessage);
- goto DONE_LBL; // --->
- }
-
- // if the name is wildcarded, loop on all items of the parent directory and
- // only retain the items which match all the criteria
- if (nWild != 0) {
- param.dirInfo.ioCompletion = nil;
- param.dirInfo.ioNamePtr = paramName;
-
- // we will exit the loop when we attempt to use a Directory Index that exceeds
- // the number of items in the directory
- for (index = 1; retVal == noErr; index++ ) {
- param.dirInfo.ioVRefNum = fss.vRefNum;
- param.dirInfo.ioDrDirID = fss.parID;
- param.dirInfo.ioFDirIndex = index;
- paramName[0] = '\0';
- retVal = PBGetCatInfo(¶m, false);
- p2cstr(paramName);
- if (retVal != noErr) {
- # ifdef DEBUG_SHOW_ERR_MESS
- strcpy(errMessage, "PBGetCatInfo 1");
- # endif
- }
- else {
-
- // check whether the item name matches the wildcarded name
- if (
- match_string((char *)paramName, theName, wilds, nWild, parms.caseS)
- ) {
-
- // The name matches. Check the selection if it is there.
- if (
- parms.only[0] == '\0'
- ||
- match_string(
- (char *)paramName,
- parms.only,
- onlyWilds,
- nOnlyWild,
- parms.caseS
- )
- ) {
-
- // The selection is not there or it is matched. Check the rest.
- if (match_criteria(¶m, &parms)) {
-
- // make an alias and attach it to the list for the reply AE
- strcpy((char *)&fss.name[1], (const char *)paramName);
- fss.name[0] = strlen((char *)paramName);
- retVal = addItem(&fss, &outList, errMessage);
-
- } // the other filtering criteria were satisfied
- } // the selection was not there or was matched
- } // the item name matched the wildcards
- } // PBGetCatInfo was successful
- } // looping on all items
- if (retVal != fnfErr) goto DONE_LBL; // --->
- retVal = noErr;
-
- } // the name was wildcarded
- else {
-
- // obtain the catalogue info to distinguish between files and folders
- c2pstr(theName);
- param.dirInfo.ioCompletion = nil;
- param.dirInfo.ioVRefNum = fss.vRefNum;
- param.dirInfo.ioNamePtr = (unsigned char *)theName;
- param.dirInfo.ioDrDirID = fss.parID;
- param.dirInfo.ioFDirIndex = 0;
- retVal = PBGetCatInfo(¶m, false);
- p2cstr(theName);
- if (retVal == noErr) {
-
- // check the selection if it is there
- if (
- parms.only[0] == '\0'
- ||
- match_string(
- theName,
- parms.only,
- onlyWilds,
- nOnlyWild,
- parms.caseS
- )
- ) {
-
- // Right. Now check the filtering criteria.
- if (match_criteria(¶m, &parms)) {
-
- // make an alias and attach it to the list that will go into the reply AE
- retVal = addItem(&fss, &outList, errMessage);
-
- } // the other filtering criteria were satisfied
- } // the selection was not there or was matched
- } // PBGetCatInfo was successful
- else if (retVal == fnfErr) {
-
- retVal = noErr;
-
- } // PBGetCatInfo could not find the item
- else {
-
- # ifdef DEBUG_SHOW_ERR_MESS
- strcpy(errMessage, "PBGetCatInfo 2");
- # endif
- goto DONE_LBL; // --->
-
- } // PBGetCatInfo returned an error
- } // the name was not wildcarded
- } // going through all descriptors in the list
-
- // prepare the reply
- retVal = AEPutParamDesc(&reply, keyDirectObject, &outList);
- if (retVal != noErr) {
- # ifdef DEBUG_SHOW_ERR_MESS
- strcpy(errMessage, "AEPutParamDesc");
- # endif
- goto DONE_LBL; // --->
- }
-
- DONE_LBL: // <---
-
- // cleanup
- if (inListCreated) {
- if (retVal == noErr) {
- retVal = AEDisposeDesc((AEDesc *)&inList);
- # ifdef DEBUG_SHOW_ERR_MESS
- if (retVal != noErr) strcpy(errMessage, "AEDisposeDesc: inList");
- # endif
- }
- else {
- (void)AEDisposeDesc((AEDesc *)&inList);
- }
- }
-
- if (outListCreated) {
- if (retVal == noErr) {
- retVal = AEDisposeDesc((AEDesc *)&outList);
- # ifdef DEBUG_SHOW_ERR_MESS
- if (retVal != noErr) strcpy(errMessage, "AEDisposeDesc: outList");
- # endif
- }
- else {
- (void)AEDisposeDesc((AEDesc *)&outList);
- }
- }
-
- if (retVal != noErr && errMessage[0] != '\0') {
- if (retVal == userCanceledErr) {
-
- // We use userCanceledErr to return a message to the user, but we have to
- // change it, otherwise AppleScript will not display any message at all. Note
- // that if the error code is userCanceledErr but there is no errMessage, we
- // don't pass here. In that case, the cancelling is passed back to AppleScript
- // as expected. Here we can use the error we like, because AppleScript only
- // display our message.
- retVal = 12345;
- }
- else {
- strcat(errMessage, "\r(");
- GetIndString(buff, WILD_miscStrRsrc, WILD_OSErrStr);
- p2cstr(buff);
- strcat(errMessage, (const char *)buff);
- NumToString((long)retVal, buff);
- p2cstr(buff);
- strcat(errMessage, (const char *)buff);
- strcat(errMessage, ")");
- }
- (void)AEPutParamPtr(
- &reply,
- keyErrorString,
- typeChar,
- errMessage,
- (Size)strlen(errMessage)
- );
- }
-
- return (retVal);
- } // main
-
- //------------------------------------------------------------------------------------------ addItem
- static OSErr addItem(
- FSSpec *fss, // --> fss of the item to be added
- AEDescList *outList, // <-> output list to be returned as reply
- char *errMessage // <-- error message
- ) {
- OSErr retVal;
- AliasHandle theAlias;
-
- # ifdef DEBUG_SHOW_ITEMS
- {
- char aStr[WILD_bufferLength];
- short k;
-
- NumToString((long)fss->vRefNum, aStr);
- k = aStr[0] + 1;
- NumToString(fss->parID, &aStr[k]);
- aStr[0] += aStr[k] + 1;
- aStr[k] = '\r';
- ParamText(aStr, "\p\r", fss->name, "");
- Alert(WILD_genericDialogRsrc, nil);
- }
- # endif
-
- // make an alias out of the FSS
- retVal = NewAliasMinimal(fss, &theAlias);
- if (retVal != noErr || theAlias == nil) {
- # ifdef DEBUG_SHOW_ERR_MESS
- strcpy(errMessage, "NewAliasMinimal");
- # endif
- }
- else {
-
- // add the item to the output descriptor list
- HLock(theAlias);
- retVal = AEPutPtr(outList, 0L, typeAlias, (Ptr)*theAlias, (*theAlias)->aliasSize);
- HUnlock(theAlias);
- if (retVal != noErr) {
- # ifdef DEBUG_SHOW_ERR_MESS
- strcpy(errMessage, "AEPutPtr");
- # endif
- }
- }
-
- return (retVal);
- } // addItem;
-